<?php

/**
 * Contains a class to display /register.php.
 *
 * PHP Version 5
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */
 
/** @uses validEmail To check email address validity. */
require_once 'function_validemail.php';
 
/** @uses valueOf For safe handling of arrays. */
require_once 'function_valueof.php';

/**
 * Includes the reCAPTCHA library for validating new users.
 * 
 * @uses recaptcha_get_html
 * @uses recaptcha_check_answer
 */
require_once 'recaptchalib.php';
 
/**
 * A class to display /register.php.
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @author   Spencer Hakim <hakims@rpi.edu>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */ 
class PageRegister extends Page
{
    /**
     * State variable.  Controls whether to process the registration or not.
     *
     * @access private
     * @var bool
     */
    private $_processRegistration;
    
    /**
     * State variable.  Controls whether to process an account activation.
     *
     * @access private
     * @var bool
     */
    private $_processActivation;
    
    /**
     * Contains the error text, if any, to display.
     *
     * @access public
     * @var string
     */
    public $error;
    
    /**
     * Constructor function.  Calls the parent constructor and sets the title.
     */
    public function __construct()
    {
        parent::__construct();
        parent::setTitle('Register');
        if (count($_POST) > 0) {
            $this->_processRegistration = true;
        }
        if (valueOf($_GET, 'code') != '') {
            $this->_processActivation = true;
        }
    }
    
    /**
     * Function to process a registration.
     *
     * @access private
     * @return bool    True on success, false on failure.
     */
    private function _register()
    {
        /** Stores the values from POST in a more usable fashion. */
        $email     = valueOf($_POST, 'email');
        $password1 = valueOf($_POST, 'password1');
        $password2 = valueOf($_POST, 'password2');
        $zip       = valueOf($_POST, 'homezip');
        $name      = valueOf($_POST, 'name');
        $phoneno   = valueOf($_POST, 'phoneno');
        $phonedesc = valueOf($_POST, 'phonedesc');
        $challenge = valueOf($_POST, 'recaptcha_challenge_field');
        $response  = valueOf($_POST, 'recaptcha_response_field');
        
        /** Determines if the passwords provided match. */
        if ($password1 != $password2) {
            $this->error = 'The passwords provided do not match.';
            return false;
        }
        
        /** Determines if the email provided is valid. */
        if (!validEmail($email)) {
            $this->error = 'The email address you provided is not valid.';
            return false;
        }
        
        /** Determines if the reCAPTCHA input is correct. Uses the private key. */
        $resp = recaptcha_check_answer(
            RECAPTCHA_PRIV_KEY, $_SERVER["REMOTE_ADDR"], $challenge, $response
        );
        if (!$resp->is_valid) {
            $this->error = 'The reCAPTCHA wasn\'t entered correctly. '
                . 'Go back and try it again. (reCAPTCHA said: '
                . $resp->error.')';
            return false;
        }
        
        /** Verifies the Zip Code */
        $zip = $this->db->getZipByZip($zip);
        if (!$zip) {
            $this->error = "The Zip Code you provided is not valid.";
            return false;
        }
        
        /** Builds a user object and attempts to register. */
        $phoneNumbers = array();
        if ($phoneno != '') {
            if ($phonedesc == '') {
                $phonedesc = 'Main';
            }
            $phoneNumbers[] = new Phone($phoneno, $phonedesc);
        }
        $user   = new User(
            '', $name, $email, $zip, R_USER, 1, '', '', $phoneNumbers
        );
        $result = $this->db->addUser($user, $password1);

        /** If user addition failed, store the error and return false. */
        if ($result !== true) {
            $this->error = $result;
            return false;
        }
        return true;
    }
    
    /**
     * Function to print an INPUT form field.
     *
     * @param string $id        The value to use for the id and name fields.
     * @param string $label     The string to insert between the <label> tags.
     * @param string $type      The type of the input field (text, password).
     * @param string $maxlength The maximum length for the input field.
     * @param string $value     The string to insert into the value attribute.
     * @param bool   $star      Defines if form field should be marked as required.
     *
     * @access private
     * @return null
     */
    private function _printFormField($id, $label, $type, $maxlength, $value, $star)
    {
        $id        = encode($id);
        $label     = encode($label);
        $type      = encode($type);
        $maxlength = encode($maxlength);
        $value     = encode($value);
        
        echo '  <div>', "\n",
            '   <label for="', $id, '">', $label, ':';

        if ($star) {
            echo '<span class="asterisk">*</span>';
        }
        
        echo '</label>', "\n",
            '   <input id="', $id, '" name="', $id, '" type="', $type, '" ',
            'maxlength="', $maxlength, '" value="', $value, '" />', "\n",
            '  </div>', "\n";
    }
    
    /**
     * Function to print the registration form.
     *
     * @access private
     * @return null
     */
    private function _printRegistrationForm()
    {
        if ($this->error != '') {
            printError($this->error, 1);
        }
        echo ' <form id="register" method="post" action="">', "\n",
            '  <h2>Required Information:</h2>', "\n";
        $this->_printFormField(
            'email', 'Email Address', 'text', L_EMAIL, valueOf($_POST, 'email'),
            true
        );
        $this->_printFormField(
            'password1', 'Password', 'password', L_PASSWORD, '', true
        );
        $this->_printFormField(
            'password2', 'Password Again', 'password', L_PASSWORD, '', true
        );
        $this->_printFormField(
            'homezip', 'Home ZIP Code', 'text', L_ZIP, valueOf($_POST, 'homezip'),
            true
        );
        echo '<div>', recaptcha_get_html(RECAPTCHA_PUB_KEY), '</div>', "\n";
        echo '  <div>', "\n",
            '   <span class="asterisk">*</span> = Required', 
            "\n",
            '  </div>', "\n";
        
        echo '  <h2>Optional Information:</h2>', "\n";
        $this->_printFormField(
            'name', 'Your Name', 'text', L_NAME, valueOf($_POST, 'name'), false
        );
        $this->_printFormField(
            'phoneno', 'Phone Number', 'text', L_PHONE, valueOf($_POST, 'phoneno'),
            false
        );
        $this->_printFormField(
            'phonedesc', 'Phone Number Description', 'text', 
            L_CONTACTDESC, valueOf($_POST, 'phonedesc'), false
        );
        
        echo '  <div>', "\n",
            '   <input type="submit" value="Register" class="button" />', "\n",
            '  </div>', "\n",
            ' </form>', "\n",
            ' <script type="text/javascript" src="scripts/registerfocus.js">',
            '</script>', "\n";
    }
    
    /**
     * Function to process an activation.
     *
     * @access private
     * @return bool    True on success, false on failure.
     */
    private function _activate()
    {
        $code  = valueOf($_GET, 'code');
        $email = valueOf($_GET, 'email');
        if ($code == '') {
            printError('No activation code provided.', 1);
            return false;
        }
        if ($email == '') {
            printError('No email provided for account activation.', 1);
            return false;
        }
        $result = $this->db->activateUser($email, $code);
        if ($result === true) {
            echo ' <p class="success">Account successfully activated!</p>', 
                "\n";
            echo ' <p>Please <a href="login.php">log in</a> to begin using ',
                'the site.</p>', "\n";
            return true;
        }
        printError($result);
        return false;
    }
    
    /**
     * Function to display the page.
     *
     * @access public
     * @return null
     */
    public function display()
    {
        if ($this->_processRegistration) {
            $this->_register();
        }
        parent::printHeader();
        if ($this->_processRegistration && $this->error == '') {
            echo ' <p class="success">Registration successful!</p>', "\n",
                ' <p>You will receive an email with an activation link ',
                'shortly.</p>', "\n";
        } else if ($this->_processActivation) {
            $this->_activate();
        } else {
            $this->_printRegistrationForm();
        }
        parent::printFooter();
    }
}

?>